<?php

namespace app\service;

use app\library\DataReturn;
use Fairy\HttpCrontab;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;

/**
 * Crontab 服务
 */
class CrontabService
{
    private $baseUri;

    /**
     * 构造方法
     */
    public function __construct()
    {
        $this->baseUri = env('CRONTAB.crontab_base_uri');
    }

    /**
     * http请求
     * @param string $url
     * @param string $method
     * @param array $formOrQuery
     * @return DataReturn
     */
    public function httpRequest(string $url, string $method = 'GET', array $formOrQuery = []): DataReturn
    {
        try {
            $client = new Client([
                'base_uri' => $this->baseUri,
            ]);
            $method = strtoupper($method);
            $options = [];
            if (!empty($formOrQuery)) {
                switch ($method) {
                    case "GET":
                        $options['query'] = $formOrQuery;
                        break;
                    case "POST":
                        $options['form_params'] = $formOrQuery;
                        break;
                }
            }
            $response = $client->request($method, $url, $options);
            $data = json_decode($response->getBody()->getContents(), true)['data'];
            return dataReturn($data);
        } catch (RequestException $e) {
            if ($e->hasResponse()) {
                $msg = json_decode($e->getResponse()->getBody()->getContents(), true)['msg'];
            } else {
                $msg = $e->getMessage();
            }
            return dataErrorReturn($msg);
        } catch (GuzzleException $e) {
            return dataErrorReturn($e->getMessage());
        }
    }

    /**
     * 计划任务列表
     * @param array $requestQueryArray 请求参数数组
     * @return DataReturn
     */
    public function CrontabList(array $requestQueryArray = []): DataReturn
    {
        return $this->httpRequest(HttpCrontab::INDEX_PATH, 'GET', $requestQueryArray);
    }

    /**
     * 添加任务
     * @param $data
     * @return DataReturn
     */
    public function add($data): DataReturn
    {
        $rule = [
            'title|标题' => 'require',
            'type|类型' => 'require',
            'frequency|频率' => 'require',
            'shell|脚本' => 'require',
        ];
        validate($rule)->check($data);
        return $this->httpRequest(HttpCrontab::ADD_PATH, 'POST', $data);
    }

    /**
     * 编辑任务
     * @param $data
     * @return DataReturn
     */
    public function edit($data): DataReturn
    {
        $rule = [
            'id|编号' => 'require',
            'title|标题' => 'require',
            'type|类型' => 'require',
            'frequency|频率' => 'require',
            'shell|脚本' => 'require',
        ];
        validate($rule)->check($data);
        $id = $data['id'];
        unset($data['id']);
        return $this->httpRequest(HttpCrontab::EDIT_PATH . '?id=' . $id, 'POST', $data);
    }

    /**
     * 获取一条任务信息
     * @param $id
     * @return DataReturn
     */
    public function read($id): DataReturn
    {
        return $this->httpRequest(HttpCrontab::READ_PATH . '?id=' . $id);
    }


    /**
     * 单个属性修改
     * @param array $modifySingleProperty
     * @return DataReturn
     */
    public function modify(array $modifySingleProperty): DataReturn
    {
        $rule = [
            'id|ID' => 'require',
            'field|字段' => 'require',
            'value|值' => 'require',
        ];
        validate($rule)->check($modifySingleProperty);
        $allowModifyFields = [
            'status',
            'sort'
        ];
        if (!in_array($modifySingleProperty['field'], $allowModifyFields)) {
            return dataErrorReturn('该字段不允许修改：' . $modifySingleProperty['field']);
        }
        return $this->httpRequest(HttpCrontab::MODIFY_PATH, 'POST', $modifySingleProperty);
    }

    /**
     * 删除任务
     * @param numeric|array $id 批量或者单个
     * @return DataReturn
     */
    public function delete($id): DataReturn
    {
        return $this->httpRequest(HttpCrontab::DELETE_PATH, 'POST', ['id' => is_array($id) ? join(',', $id) : $id]);
    }

    /**
     * 重启
     * @param numeric|array $id
     * @return DataReturn
     */
    public function reload($id = ''): DataReturn
    {
        $form = [];
        if (!empty($id)) {
            $form = [
                'id' => is_array($id) ? join(',', $id) : $id
            ];
        }
        return $this->httpRequest(HttpCrontab::RELOAD_PATH, 'POST', $form);
    }

    /**
     * 心跳检测
     * @return DataReturn
     */
    public function ping(): DataReturn
    {
        return $this->httpRequest(HttpCrontab::PING_PATH);
    }

    /**
     * 获取日志
     * @param array $requestQueryArray
     * @return DataReturn
     */
    public function flow(array $requestQueryArray = []): DataReturn
    {
        return $this->httpRequest(HttpCrontab::FLOW_PATH, "GET", $requestQueryArray);
    }

    /**
     * 定时器池
     * @return DataReturn
     */
    public function pool(): DataReturn
    {
        return $this->httpRequest(HttpCrontab::POOL_PATH);
    }


}